# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName:   selenium_self
# FileName:      basic.py
# Author:       test_liu
# Datetime:     2024/10/14 下午8:04
# Description: 启动浏览器，二次封装selenium
# ---------------------------------------------------------------------------
import os
import time

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from WebTest2.WebTest import log
from WebTest2.WebTest.common.read_local_ini import ReadLocalIni


class Basic:
    def __init__(self, web='e'):
        self.ini = ReadLocalIni()
        # 没有用无头模式，不需要浏览器安装路径
        if web == 'e':  # 启动edge浏览器
            driver_path = self.ini.get_driver_path('edge')
            self.driver = webdriver.Edge(service=webdriver.EdgeService(executable_path=driver_path))
        elif web == 'c':  # 启动chrome浏览器
            driver_path = self.ini.get_driver_path('chrome')
            self.driver = webdriver.Chrome(service=webdriver.ChromeService(executable_path=driver_path))
        else:
            log.error('指定浏览器错误')
            raise Exception('请输入正确的浏览器类型')

        # 浏览器窗口最大化
        self.driver.maximize_window()
        # 访问对应系统
        self.driver.get(self.ini.get_url('url'))
        # 创建WebDriverWait的对象，后续需要使用---显示等待使用
        self.explicit_wait = WebDriverWait(self.driver, 20, 0.5)

    def selector_local(self, strs):
        """
        传入的字符串为：i | username ===> (By.ID, 'username')
        传入的字符串为：n | password ===> (By.NAME, 'password')
        传入的字符串为：s |index.spit ===> (By.CLASS_NAME, 'spit.spit')
        传入的字符串为：t|input ===> (By.TAG_NAME, 'input')
        传入的字符串为：l|贴吧 ===> (By.LINK_TEXT, '贴吧')
        传入的字符串为：p|新 ===> (By.PARTIAL_LINK_TEXT, '新')
        传入的字符串为：x|//*[text()="退出"] ===> (By.XPATH, '//*[text()="退出"]')
        传入的字符串为：c|[placeholder=”请输入别把“] ===> (By.CSS_SELECTOR, '[placeholder=”请输入别把“]')
        :param strs: 定位的方式和定位的值之间以|间隔
        :return: tuple
        """
        # 分割|，前面为selector，后面为local
        selector = strs.split('|')[0].strip().lower()
        local = strs.split('|')[1].strip()
        if selector == 'i' or selector == 'id':
            return By.ID, local
        elif selector == 'n' or selector == 'name':
            return By.NAME, local
        elif selector == 's' or selector == 'class':
            return By.CLASS_NAME, local
        elif selector == 't' or selector == 'tag':
            return By.TAG_NAME, local
        elif selector == 'l' or selector == 'link':
            return By.LINK_TEXT, local
        elif selector == 'p' or selector == 'partial':
            return By.PARTIAL_LINK_TEXT, local
        elif selector == 'x' or selector == 'xpath':
            return By.XPATH, local
        elif selector == 'c' or selector == 'css':
            return By.CSS_SELECTOR, local
        else:
            log.error(f'请输入正确的定位，传入的字符串为{strs}')
            raise Exception(f'请输入正确的定位，传入的字符串为{strs}')

    def presence(self, strs):
        """显示等待的presence_of_element_located（单个元素出现定位）进行二次封装"""
        selector = self.selector_local(strs)
        return self.explicit_wait.until(EC.presence_of_element_located(selector))

    def presences(self, strs):
        """显示等待的presence_of_element_located（多个元素出现定位）进行二次封装"""
        selector = self.selector_local(strs)
        return self.explicit_wait.until(EC.presence_of_all_elements_located(selector))

    def clickable(self, strs):
        """显示等待的element_to_be_clickable（判断元素可点击）进行二次封装"""
        selector = self.selector_local(strs)
        return self.explicit_wait.until(EC.element_to_be_clickable(selector))

    def send_key(self, strs, value):
        """对send_key二次封装
            根据单个元素定位定位的字符串，获取到元素"""
        element = self.presence(strs)
        # 对元素进行send_keys操作
        element.send_keys(value)

    def click(self, strs):
        """对click进行二次封装，使用到之前封装的clickable函数"""
        element = self.clickable(strs)
        # 对元素进行click操作
        element.click()

    def screenshot(self, file_name):
        """对截图二次封装"""
        time.sleep(0.1)
        img_path = os.path.join(self.ini.get_report("img"), file_name)
        self.driver.get_screenshot_as_file(img_path)

    def text(self, strs):
        """对元素的text进行二次封装"""
        return self.presence(strs).text


if __name__ == '__main__':
    b = Basic('e')
    str1 = 'i | username'
    res = b.selector_local(str1)
    print(res, type(res))